package org.grayrabbit.cloud.utils.logger;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggerWrapper{
	
	private static ConcurrentHashMap<String,LoggerOutput> outs 
	= new ConcurrentHashMap<String,LoggerOutput>();		
	private Logger logger = null;	
	private String name = null;	
	
	public LoggerWrapper(String name){
		this.name = name;
		this.logger = Logger.getLogger(name);		
	}
	
	public static LoggerWrapper getLogger(String name){
		return new LoggerWrapper(name);
	}
	
	public static LoggerWrapper getLogger(Class<?> clazz){
		return new LoggerWrapper(clazz.getName());
	}
	
	public static void start(String uid,LoggerOutput out){
		outs.put(uid, out);
	}
	
	public static void close(String uid){
		outs.remove(uid);
	}
		
	public static void setBaseRootLevel(int level){
		if(level<Level.DEBUG_INT)	level=Level.ALL_INT;
		if(level>Level.FATAL_INT)	level=Level.OFF_INT;
//		Logger.getRootLogger()..setLevel(Level.toLevel(level));
	}
	
	public static void setBaseLoggerLevel(String logName,int level){
		if(level<Level.DEBUG_INT)	level=Level.ALL_INT;
		if(level>Level.FATAL_INT)	level=Level.OFF_INT;
//		Logger.getLogger(logName).setLevel(Level.toLevel(level));
	}
	
	public static void setOutputLoggerLevel(String uid,int level){
		LoggerOutput out = outs.get(uid);
		if(out!=null){
			if(level<Level.DEBUG_INT)	level=Level.ALL_INT;
			if(level>Level.FATAL_INT)	level=Level.OFF_INT;
			out.setLevel(level);
			outs.put(uid, out);
		}
	}
	
	public static void setOutputLoggerPause(String uid,boolean b){
		LoggerOutput out = outs.get(uid);
		if(out!=null){
			out.setPause(b);
			outs.put(uid, out);
		}
	}
	
	public static void setOutputLoggerFilter(String uid,String filter){
		LoggerOutput out = outs.get(uid);
		if(out!=null){
			String sfilter = "a";
			if(filter.equalsIgnoreCase("s"))	sfilter = "SServerModule";
			else if(filter.equalsIgnoreCase("c"))	sfilter = "SClientModule";
			out.setFilter(sfilter);
			outs.put(uid, out);
		}
	}
	
	public void debug(Object message){		
		if(logger!=null)	logger.debug(message);		
		output(message,Level.DEBUG_INT);
	}
	
	public void debug(Object message, Throwable t){		
		if(logger!=null)	logger.debug(message,t);
		output(message,Level.DEBUG_INT);
	}
	
	public void error(Object message){		
		if(logger!=null)	logger.error(message);	
		output(message,Level.ERROR_INT);
	}
	
	public void error(Object message, Throwable t){		
		if(logger!=null)	logger.error(message,t);
		output(message,Level.ERROR_INT);
	}
	
	public void fatal(Object message){		
		if(logger!=null)	logger.fatal(message);
		output(message,Level.FATAL_INT);
	}
	
	public void fatal(Object message, Throwable t){		
		if(logger!=null)	logger.fatal(message,t);
		output(message,Level.FATAL_INT);
	}
	
	public void info(Object message){		
		if(logger!=null)	logger.info(message);
		output(message,Level.INFO_INT);
	}
	
	public void info(Object message, Throwable t){		
		if(logger!=null)	logger.info(message,t);
		output(message,Level.INFO_INT);
	}
	
	public void warn(Object message){		
		if(logger!=null)	logger.warn(message);
		output(message,Level.WARN_INT);
	}
	
	public void warn(Object message, Throwable t){		
		if(logger!=null)	logger.warn(message,t);
		output(message,Level.WARN_INT);
	}
	
	private void output(Object message,int level){		
		
		if(outs.size()<1)	return;		
		for (Enumeration<String> keys= outs.keys(); keys.hasMoreElements();) {
	         String key = keys.nextElement();
	         LoggerOutput out = outs.get(key);
	         if(out.isEnable(level) && 
	        	(out.getFilter().equals("a") || out.getFilter().equals(name))){	
	        	 
	        	 StringBuffer sb = new StringBuffer();
	     		 sb.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
	     		 if(level==Level.DEBUG_INT)	sb.append(" DEBUG");
	     		 else if(level==Level.ERROR_INT)	sb.append(" ERROR");
	     		 else if(level==Level.FATAL_INT)	sb.append(" FATAL");
	     		 else if(level==Level.INFO_INT)	sb.append(" INFO");
	     		 else if(level==Level.WARN_INT)	sb.append(" WARN");
	     		 sb.append(" ").append(name);
	     		 sb.append(" ").append(message);
	        	 
		         try{
					out.writeln(sb.toString());
				 }catch(Exception e){
					 logger.warn("destroy unkown client connection");
					 outs.remove(key);
				 }
	         }
	     }
		
		
	}
	
}
